//消息的加解密
var CodeMsg = {};
//加密数据
CodeMsg.EncryptBufferS = function (pcbDataBuffer,wBufferSize)
{
    //效验码与字节映射
    var cbCheckCode = 0;
    for (var i = cc.TCP_INFO_SIZE; i<wBufferSize; i++){
        cbCheckCode += pcbDataBuffer[i];
        pcbDataBuffer[i] = gQPCipher.MapSendByteS(pcbDataBuffer,i);
    }
    //填写信息头
    gCByte.w1( pcbDataBuffer,1,~cbCheckCode + 1);

    //设置变量
    this.m_dwSendPacketCount++;
    return wBufferSize;
},

//解密数据
CodeMsg.CrevasseBufferS = function(pcbDataBuffer,wBufferSize){
    //效验码与字节映射
    var cbCheckCode = new Uint8Array(1);
    cbCheckCode[0] = pcbDataBuffer[1];
    for (var i = cc.TCP_INFO_SIZE; i<wBufferSize; i++){
        var cbRecvRound = new Uint8Array(1);
        pcbDataBuffer[i] = gQPCipher.MapRecvByteS(pcbDataBuffer,i);
        cbCheckCode[0] += pcbDataBuffer[i];
    }
    if (cbCheckCode[0] != 0) if(LOG_NET_DATA)console.log('CheckCode Error.');
},

//加密数据
CodeMsg.EncryptBuffer = function(pcbDataBuffer,wDataSize,wBufferSize)
{
    //调整长度
    var wEncryptSize = wDataSize - cc.TCP_COMMACN_SIZE, wSnapCount = 0;
    if ((wEncryptSize%cc.DWORD_SIZE) != 0){
        wSnapCount = cc.DWORD_SIZE-wEncryptSize%cc.DWORD_SIZE;
    }

    //效验码与字节映射
    var cbCheckCode = 0;
    for (var i = cc.TCP_INFO_SIZE; i<wDataSize; i++){
        cbCheckCode += pcbDataBuffer[i];
        var cbSendRound = new Uint8Array(1);
        cbSendRound[0] = this.m_cbSendRound;
        pcbDataBuffer[i] = gQPCipher.MapSendByteS(pcbDataBuffer,i, cbSendRound);
        this.m_cbSendRound = cbSendRound[0];
    }
    //填写信息头
    //cbDataKind
    gCByte.w1(pcbDataBuffer,0,cc.SOCKET_VER);
    //cbCheckCode
    gCByte.w1( pcbDataBuffer,1,~cbCheckCode + 1);
    //wPacketSize
    gCByte.w2(pcbDataBuffer,2,wDataSize);

    //创建密钥
    var dwXorKey = this.m_dwSendXorKey;
    if (this.m_dwSendPacketCount == 0){
        //生成第一次随机种子
        dwXorKey = 99999;
        dwXorKey ^= 1;
        dwXorKey ^= 1;
        dwXorKey ^= 1;
        dwXorKey ^= 1;

        //随机映射种子
        dwXorKey = this.SeedRandMap(dwXorKey&0xFFFF);
        dwXorKey |= (this.SeedRandMap((dwXorKey >> 16)&0xFFFF)&0xFFFFFFFF) << 16;
        dwXorKey ^= g_dwPacketKey;
        this.m_dwSendXorKey = dwXorKey;
        this.m_dwRecvXorKey = dwXorKey;
    }

    //加密数据
    var wEncrypCount = (wEncryptSize + wSnapCount) / cc.DWORD_SIZE;
    var t = 0;
    var tt = 0;
    for (var i = 0; i<wEncrypCount; i++){
        gCByte.w4(pcbDataBuffer,cc.TCP_INFO_SIZE+tt,gCByte.r4(pcbDataBuffer,cc.TCP_INFO_SIZE+tt)&0xFFFFFFFF ^ (dwXorKey&0xFFFFFFFF));
        tt+=cc.DWORD_SIZE;
        dwXorKey = this.SeedRandMap(gCByte.r2(pcbDataBuffer,cc.TCP_INFO_SIZE+t));
        t+=cc.WORD_SIZE;
        dwXorKey |= (this.SeedRandMap(gCByte.r2(pcbDataBuffer,cc.TCP_INFO_SIZE+t))&0xFFFFFFFF) << 16;
        t+=cc.WORD_SIZE;
        dwXorKey ^= g_dwPacketKey;
    }

    //插入密钥
    if (this.m_dwSendPacketCount == 0) {
        for(var i = wDataSize+wSnapCount;i>cc.TCP_HEAD_SIZE;i--)
        {
            pcbDataBuffer[i+cc.DWORD_SIZE-1] = pcbDataBuffer[i-1];
        }

        gCByte.w4(pcbDataBuffer,cc.TCP_HEAD_SIZE,this.m_dwSendXorKey);
        //wPacketSize
        gCByte.w2(pcbDataBuffer,2,gCByte.r2(pcbDataBuffer,2)+cc.DWORD_SIZE);
        wDataSize += cc.DWORD_SIZE;
    }
    //设置变量
    this.m_dwSendPacketCount++;
    this.m_dwSendXorKey = dwXorKey;

    return wDataSize;
},

//解密数据
CodeMsg.CrevasseBuffer = function (pcbDataBuffer,wDataSize){
    //调整长度
    var wSnapCount = 0;
    if ((wDataSize%cc.DWORD_SIZE) != 0)
    {
        wSnapCount = cc.DWORD_SIZE-wDataSize%cc.DWORD_SIZE;
        for(var i=0;i<wSnapCount;i++){
            pcbDataBuffer[wDataSize+i] = 0;
        }
    }
    //解密数据
    var dwXorKey = this.m_dwRecvXorKey;
    var wEncrypCount = (wDataSize + wSnapCount - cc.TCP_INFO_SIZE) / 4;
    var t = 0;
    var tt = 0;
    for (var i = 0; i<wEncrypCount; i++){
        if ((i == (wEncrypCount - 1)) && (wSnapCount>0))
        {
            var pcbKey = new Uint8Array(cc.DWORD_SIZE);
            gCByte.w4(pcbKey,0,this.m_dwRecvXorKey);
            var cbKey = new Uint8Array(cc.DWORD_SIZE);
            var j=0;
            for(var ts=cc.DWORD_SIZE-wSnapCount;ts<cc.DWORD_SIZE;ts++)
            {
                cbKey[j++] = pcbKey[ts];
            }
            for(var ts=0;ts<wSnapCount;ts++)
            {
                pcbDataBuffer[wDataSize+ts] = cbKey[ts];
            }
        }
        /*
        if ((i == (wEncrypCount - 1)) && (wSnapCount>0))
        {
            BYTE * pcbKey = ((BYTE *)&m_dwRecvXorKey) + sizeof(DWORD)-wSnapCount;
            memcpy(pcbDataBuffer + wDataSize, pcbKey, wSnapCount);
        }
        */

        dwXorKey = this.SeedRandMap(gCByte.r2(pcbDataBuffer,cc.TCP_INFO_SIZE+t));
        t+=cc.WORD_SIZE;
        dwXorKey |= (this.SeedRandMap(gCByte.r2(pcbDataBuffer,cc.TCP_INFO_SIZE+t))&0xFFFFFFFF) << 16;
        t+=cc.WORD_SIZE;
        dwXorKey ^= g_dwPacketKey;
        gCByte.w4(pcbDataBuffer,cc.TCP_INFO_SIZE+tt,gCByte.r4(pcbDataBuffer,cc.TCP_INFO_SIZE+tt)&0xFFFFFFFF ^ (this.m_dwRecvXorKey&0xFFFFFFFF));
        tt+=cc.DWORD_SIZE;
        this.m_dwRecvXorKey = dwXorKey;
    }

    //效验码与字节映射
    var cbCheckCode = new Uint8Array(1);
    cbCheckCode[0] = pcbDataBuffer[1];
    for (var i = cc.TCP_INFO_SIZE; i<wDataSize; i++)
    {
        var cbRecvRound = new Uint8Array(1);
        cbRecvRound[0] = this.m_cbRecvRound;
        pcbDataBuffer[i] = gQPCipher.MapRecvByte(pcbDataBuffer,i, cbRecvRound);
        this.m_cbRecvRound = cbRecvRound[0];
        cbCheckCode[0] += pcbDataBuffer[i];
    }
    if (cbCheckCode[0] != 0) if(LOG_NET_DATA)console.log('CheckCode Error.');
},

//随机映射
CodeMsg.SeedRandMap = function (wSeed)
{
    var dwHold = wSeed;
    return ((dwHold = dwHold * 241103 + 2533101) >> 16)&0xFFFF;
}
